
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>非阻塞 I/O 模型 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>非阻塞 I/O 模型 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">非阻塞 I/O 模型与传统的阻塞 I/O 模型在线程行为上有何根本区别？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">在传统的阻塞 I/O 模型中，线程发起 I/O 请求后会被阻塞直到操作完成。而在非阻塞 I/O 模型中，线程发起 I/O 请求后，如果操作无法立即完成，线程会返回并继续执行其他任务，不会被阻塞。</div>
          </div>
          <div class="card-source">来源: 1. 非阻塞 I/O 模型概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">Netty 是如何利用 Java NIO 实现其非阻塞 I/O 模型的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Netty 通过使用 Java NIO（New I/O）中提供的两个核心组件：`Selector`（用于监听多个通道的 I/O 事件）和 `Channel`（表示网络通信端点）来实现非阻塞 I/O 模型。</div>
          </div>
          <div class="card-source">来源: 1. 非阻塞 I/O 模型概述</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在 Netty 的非阻塞 I/O 架构中，`Channel`、`Selector` 和 `EventLoop` 这三个核心组件分别扮演什么角色？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">Channel：表示与网络通信的端点。<br>Selector：用于监听多个通道的 I/O 事件。<br>EventLoop：负责在非阻塞的情况下处理 I/O 事件。</div>
          </div>
          <div class="card-source">来源: 2. Netty 的非阻塞 I/O 模型架构</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">在 Netty 的 `NioSocketChannel` 中，是如何将一个 `Channel` 设置为非阻塞模式的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">通过调用 `socketChannel.configureBlocking(false)` 方法，将底层的 Java NIO `SocketChannel` 设置为非阻塞模式。这样，在执行读取等操作时，如果数据未就绪，线程不会被阻塞。</div>
          </div>
          <div class="card-source">来源: 3. 非阻塞 Channel 的工作原理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">Netty 中的 `EventLoopGroup` 的主要职责是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`EventLoopGroup` 是一个管理多个事件循环（EventLoop）线程的容器。它的职责是为新接入的连接分配一个 `EventLoop` 线程，该线程将负责处理该连接上的所有 I/O 事件。</div>
          </div>
          <div class="card-source">来源: 4. 事件循环（EventLoop）的管理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">请简述 Netty 中非阻塞 I/O 操作的四个主要流程。</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. 连接事件：Channel 建立连接后注册到 Selector 上。<br>2. 选择器等待：EventLoop 线程调用 `selector.select()` 等待 I/O 事件发生。<br>3. 事件分发：Selector 检测到事件后，通知 EventLoop 进行处理。<br>4. 处理事件：EventLoop 线程处理具体的 I/O 事件，如读取或写入数据。</div>
          </div>
          <div class="card-source">来源: 5. 非阻塞 I/O 操作流程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">Java NIO 中的 `Selector` 是什么，它的核心功能是什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`Selector` 是 Java NIO 提供的一个核心组件，其核心功能是作为多路复用器，用于检查一个或多个 `Channel` 上是否有 I/O 事件发生（如连接、可读、可写）。</div>
          </div>
          <div class="card-source">来源: 6. 非阻塞 I/O 与 NIO 的关系</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在 `NioEventLoop` 的运行循环中，`selector.select()` 方法起到了什么关键作用？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">`selector.select()` 方法会阻塞等待，直到其监听的一个或多个通道上有 I/O 事件准备就绪。一旦有事件发生，该方法会返回就绪的通道数量，从而唤醒 `EventLoop` 线程来处理这些事件。</div>
          </div>
          <div class="card-source">来源: 6. 非阻塞 I/O 与 NIO 的关系</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">根据文档，采用非阻塞 I/O 模型主要能带来哪三大优势？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">1. 高并发：一个线程可以处理多个通道的 I/O 事件，减少了线程创建开销。<br>2. 降低阻塞：线程在等待 I/O 时可以执行其他任务，提高了 CPU 利用率。<br>3. 响应时间短：通过事件驱动方式，能在事件发生时快速响应和处理。</div>
          </div>
          <div class="card-source">来源: 7. 非阻塞 I/O 的优势</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
